// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

#include "DBManager/Repository/HDF5/Input/Design/DTABLE2Repository.h"

#include "DBManager/Repository/HDF5/Base/HDF5RepositoryMacro.h"

HDF5_REG_NO_SORT_REPOSITORY (DTABLE2Repository)

using namespace SG::DBManager::HDF5;
using namespace SG::DataStructure;
using namespace SG::DataStructure::FEM;
using namespace SG::DataStructure::Common;

// 构造函数实现
DTABLE2Repository::DTABLE2Repository (HDF5Database& database) : RepositoryBase (database)
{}

void DTABLE2Repository::InitialDatasetInfo ()
{
    RegisterTableInfo<NasMainStruct> ("/SG/INPUT/DESIGN/DTABLE2/IDENTITY", MainDataset);
    RegisterTableInfo<SubStructVALUES> ("/SG/INPUT/DESIGN/DTABLE2/VALUES", SubDataset_VALUES);
}

/// @brief 写入配置
/// @param entity
SG::DataStructure::Common::Status DTABLE2Repository::Set (const SG::DataStructure::FEM::DTABLE2Data& entity)
{
    NasMainStruct                IDENTITYData;
    std::vector<SubStructVALUES> subDataVALUES;
    OwnToNastran (entity, IDENTITYData, subDataVALUES);

    CoverLocalData (this->GetDatasetInfo (MainDataset), IDENTITYData);
    CoverLocalData (this->GetDatasetInfo (SubDataset_VALUES), 0, subDataVALUES);

    return SG::DataStructure::Common::Status::STATUS_Success;
}

/// @brief 获取配置
/// @return
SG::DataStructure::FEM::DTABLE2Data DTABLE2Repository::Get ()
{
    NasMainStruct                IDENTITYData;
    std::vector<SubStructVALUES> subDataVALUES;
    {
        // 获取数据集的路径和数据集对象
        HighFive::DataSet dataset = this->GetDataset (MainDataset);
        // 写出数据
        dataset.select ({ 0 }, { 1 }).read (IDENTITYData);
    }

    {
        // 获取数据集的路径和数据集对象
        HighFive::DataSet dataset = this->GetDataset (SubDataset_VALUES);
        // 写出数据
        dataset.select ({ static_cast<UI64> (IDENTITYData.START) }, { static_cast<UI64> (IDENTITYData.LEN) }).read (subDataVALUES);
    }

    MainStruct OwnIdent;

    NastranToOwn (IDENTITYData, subDataVALUES, OwnIdent);

    return OwnIdent;
}

void DTABLE2Repository::OwnToNastran (const MainStruct&                  OwnIdent,
                                      NasMainStruct& _OUT                IDENTITYData,
                                      std::vector<SubStructVALUES>& _OUT subDataVALUES,
                                      bool                               isSort)
{
    subDataVALUES.clear ();
    // 获取已有数据条数，主要是放在主表的POS字段
    // 如果是重新排序的时候，Pos都是从0 开始的
    size_t countVALUES = isSort ? 0 : this->GetDatasetInfo (SubDataset_VALUES).GetRowCount ();

    // OwnIdent 代表咱们自己的数据结构
    // NasIdent 代表nastran的数据结构
    // 写入附表
    subDataVALUES.insert (subDataVALUES.end (), OwnIdent.m_VALUESList.begin (), OwnIdent.m_VALUESList.end ());

    const size_t lenVALUES = OwnIdent.m_VALUESList.size ();

    // 写入IDENTITY
    IDENTITYData.DOMAIN_ID = OwnIdent.m_domainId;

    IDENTITYData.START = static_cast<I64> (countVALUES);

    IDENTITYData.LEN = static_cast<I64> (lenVALUES);
}

void DTABLE2Repository::NastranToOwn (NasMainStruct& IDENTITYData, std::vector<SubStructVALUES>& subDataVALUES, MainStruct& _OUT OwnIdent)
{
    OwnIdent.m_domainId = IDENTITYData.DOMAIN_ID;

    if (IDENTITYData.LEN != 0)
    {
        OwnIdent.m_VALUESList.assign (subDataVALUES.begin () + IDENTITYData.START - IDENTITYData.START,
                                      subDataVALUES.begin () + IDENTITYData.START + IDENTITYData.LEN - IDENTITYData.START);
    }
}
